package com.xuecheng.media.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.media.dto.MediaDTO;
import com.xuecheng.api.media.qo.QueryMedia;
import com.xuecheng.api.media.vo.MediaAuditVo;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.common.AuditEnum;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.media.common.utils.AliyunVODUtil;
import com.xuecheng.media.convert.MapStructMedia;
import com.xuecheng.media.entity.Media;
import com.xuecheng.media.mapper.MediaMapper;
import com.xuecheng.media.service.MediaService;
import com.xuecheng.openfeign.Media4Course;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 媒资信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {

    @Value("${aliyun.region}")
    private String region;
    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;

    @Autowired
    private Media4Course media4Course;

    /**
     * @param mediaDTO
     * @return com.xuecheng.api.media.dto.MediaDTO
     * @Description //保存媒资信息
     * @Date 2021/12/14 21:08
     * @Param [mediaDTO] 响应-->po封装成dto响应
     * 业务分析
     * 关键数据
     * fileid。filename   buket  company_id
     * 业务数据
     * 将其状态修改为未审核
     */
    @Override
    @Transactional
    public MediaDTO saveMedia(MediaDTO mediaDTO) {
        //判断其关键数据
        if (ObjectUtils.isEmpty(mediaDTO.getCompanyId()) ||
                StringUtils.isBlank(mediaDTO.getFileId()) ||
                StringUtils.isBlank(mediaDTO.getFilename()) ||
                StringUtils.isBlank(mediaDTO.getType())) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //将其状态修改为未审核
        mediaDTO.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());
        mediaDTO.setChangeDate(LocalDateTime.now());
        //DTO转化为po数据
        Media media = MapStructMedia.INSTANCE.dto2Po(mediaDTO);
        //保存数据
        boolean save = this.save(media);
        //判断是否保存成功
        if (!save) {
            ExceptionCast.cast(CommonErrorCode.E_100106);
        }
        //重新查询返回最新数据
        Media queryMedia = this.getById(media.getId());
        //将其po转化为dto
        MediaDTO mediaDTO1 = MapStructMedia.INSTANCE.po2DTO(queryMedia);
        return mediaDTO1;
    }

    /**
     * @param page
     * @param media
     * @param companyId
     * @return void
     * @Description //分页或者模糊查询所有的媒资信息
     * @Date 2021/12/14 22:33
     * @Param [page, media, companyId]
     * 业务分析
     * 关键数据
     * 机构id不能为空->
     * 业务数据
     * 是否被删除
     */
    @Override
//    @Transactional
    public PageVO queryMediaList(PageRequestParams page, QueryMedia media, Long companyId) {
        //判斷分頁數據是否合法
        if (page.getPageNo() < 1) {
            page.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }

        //判斷分頁條件---每頁條數是否合法
        if (page.getPageSize() < 1) {
            page.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }

        //構建查詢對象
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();

        //查詢--如果課程的審核狀態不爲空.則其根據課程狀態精確匹配查詢
        queryWrapper.eq(StringUtil.isNotBlank(media.getType()),
                Media::getType, media.getType());

        //查詢,如果課程的名字不為空.則其模糊查詢跟其所有相關的數據
        queryWrapper.like(StringUtils.isNotBlank(media.getFilename()),
                Media::getFilename, media.getFilename());

        queryWrapper.eq(Media::getCompanyId, companyId);


        //創建分頁查詢對象
        Page<Media> courseBasePage = new Page<>(page.getPageNo(), page.getPageSize());

        //根據查詢對象和分頁開始查詢
        Page<Media> pageList = this.page(courseBasePage, queryWrapper);

        //獲取這一頁的數據
        List<Media> records = pageList.getRecords();

        //将这一页的数据通过MapStruct工具转换为List<>
        List<MediaDTO> mediaDto = new ArrayList<>();
        if (!CollectionUtils.isEmpty(records)) {
            mediaDto = MapStructMedia.INSTANCE.pos2Dtos(records);
        }
        //獲取總條數
        long total = pageList.getTotal();

        //將查詢條件封裝到pageVO中
        //  PageVO(List<T> items, long counts, long page, long pageSize) {
        PageVO courseBases =
                new PageVO<>(mediaDto, total, page.getPageNo(), page.getPageSize());

        //返回數據
        return courseBases;
    }

    /**
     * @param mediaId
     * @param companyId
     * @return java.lang.String
     * @Description //根据媒资id获取媒资预览地址
     * @Date 2021/12/14 22:56
     * @Param [mediaId, companyId] 媒资id和教育机构id
     * 业务分析
     * 判断关键数据
     * mediaId companyId不能为空
     * 业务数据
     * 判断媒资信心是否存在
     * 判断是否是视频类型-->需要阿里云获取视频地址
     * 开始阿里云获取地址--返回
     */
    @Override
    public String previewMedia(Long mediaId, Long companyId) {
        //判断关键数据
        if (ObjectUtils.isEmpty(mediaId) ||
                ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //在媒资列表查询相关信息
        LambdaQueryWrapper<Media> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Media::getId, mediaId);
        wrapper.eq(Media::getCompanyId, companyId);
        Media media = this.getOne(wrapper);
        //判断业务数据
        if (ObjectUtils.isEmpty(media)) {
            ExceptionCast.cast(CommonErrorCode.E_100104);
        }
        //初始化客户端
        try {
            DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);

            GetPlayInfoResponse playInfo = AliyunVODUtil.getPlayInfo(client, media.getFileId());

            //获取地址-->视频可能存在播放清晰度.所以为集合形式
            List<GetPlayInfoResponse.PlayInfo> list = playInfo.getPlayInfoList();
            String playURL = "";
            if (!(CollectionUtils.isEmpty(list))) {
                GetPlayInfoResponse.PlayInfo info = list.get(0);
                playURL = info.getPlayURL();
            }
            return playURL;
        } catch (Exception e) {
            //切记不能用 e.printStackTrace();
            log.error("当钱错误；{}", e.getMessage());
            return null;
        }

    }

    /**
     * @param mediaId
     * @param companyId
     * @return void
     * @Description //删除媒资信息
     * @Date 2021/12/14 23:20
     * @Param [mediaId, companyId]
     * 业务分析
     * 关键数据-->机构id和媒资id不能为空
     * 业务数据-->判断是否存在.判断审核状态.判断媒资信息是否绑定了课程计划
     * <p>
     * 删除数据-->media数据--》阿里云视频
     */
    @Override
    @Transactional
    public void deleteMedia(Long mediaId, Long companyId) {
        //关键数据
        if (ObjectUtils.isEmpty(mediaId) ||
                ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //根据id查询和教育机构id查询媒资信息
        LambdaQueryWrapper<Media> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Media::getId, mediaId);
        wrapper.eq(Media::getCompanyId, companyId);
        Media media = this.getOne(wrapper);
        if (ObjectUtils.isEmpty(media)) {
            ExceptionCast.cast(CommonErrorCode.E_100104);
        }
        //根据媒资id利用feign远程调用查询teachplan_media
        boolean b = media4Course.teachplanMediaDTO(mediaId);
        if (!b) {
            ExceptionCast.cast(CommonErrorCode.E_110004);
        }
////        LambdaUpdateWrapper<Media> queryWrapper = new LambdaUpdateWrapper<>();
//        queryWrapper.eq(Media::getId, mediaId);
//        boolean update = this.update(queryWrapper);
        boolean delete = this.removeById(mediaId);
        if (!delete) {
            ExceptionCast.cast(CommonErrorCode.E_110009);
        }

        try {
            DefaultAcsClient client1 = AliyunVODUtil
                    .initVodClient(region, accessKeyId, accessKeySecret);
            GetPlayInfoResponse playInfo = AliyunVODUtil.getPlayInfo(client1, media.getFileId());
            if (playInfo != null) {
                try {
                    //初始化客户端
                    DefaultAcsClient client = AliyunVODUtil
                            .initVodClient(region, accessKeyId, accessKeySecret);
                    AliyunVODUtil.deleteVideo(client, media.getFileId());
                } catch (Exception e) {
                    log.error("当前删除阿里云端视频失败.错误袁婷=={}", e.getMessage());
                    ExceptionCast.cast(CommonErrorCode.E_110010);
                }
            }
        } catch (Exception e) {
            log.error("当前删除阿里云端视频失败.错误袁婷=={}", e.getMessage());
            ExceptionCast.cast(CommonErrorCode.E_110010);
        }


    }

    /**
     * @param page
     * @param media
     * @param
     * @return com.xuecheng.common.domain.page.PageVO
     * @Description //运营商获取所有的媒资已经提交的数据
     * @Date 2021/12/15 17:42
     * @Param [page, media, companyId]
     * 业务分析
     * companyId
     */
    @Override
    public PageVO queryMediaAuditList(PageRequestParams page, QueryMedia media) {
        //判斷分頁數據是否合法
        if (page.getPageNo() < 1) {
            page.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }

        //判斷分頁條件---每頁條數是否合法
        if (page.getPageSize() < 1) {
            page.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }

        //構建查詢對象
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();

        //查詢--如果課程的審核狀態不爲空.則其根據課程狀態精確匹配查詢
        queryWrapper.eq(StringUtil.isNotBlank(media.getType()),
                Media::getType, media.getType());

        //查詢,如果課程的名字不為空.則其模糊查詢跟其所有相關的數據
        queryWrapper.like(StringUtils.isNotBlank(media.getFilename()),
                Media::getFilename, media.getFilename());
        if (media.getAuditStatus().equals(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode())) {
            queryWrapper.eq(Media::getAuditStatus, CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode());
        }

//        queryWrapper.eq(Media::getCompanyId, companyId);
//        queryWrapper.eq(Media::getAuditStatus, CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode());

        //創建分頁查詢對象
        Page<Media> courseBasePage = new Page<>(page.getPageNo(), page.getPageSize());

        //根據查詢對象和分頁開始查詢
        Page<Media> pageList = this.page(courseBasePage, queryWrapper);

        //獲取這一頁的數據
        List<Media> records = pageList.getRecords();

        //将这一页的数据通过MapStruct工具转换为List<>
        List<MediaDTO> mediaDto = new ArrayList<>();
        if (!CollectionUtils.isEmpty(records)) {
            mediaDto = MapStructMedia.INSTANCE.pos2Dtos(records);
        }
        //獲取總條數
        long total = pageList.getTotal();

        //將查詢條件封裝到pageVO中
        //  PageVO(List<T> items, long counts, long page, long pageSize) {
        PageVO courseBases =
                new PageVO<>(mediaDto, total, page.getPageNo(), page.getPageSize());

        //返回數據
        return courseBases;
    }

    /**
     * @param mediaAuditVo
     * @return void
     * @Description //媒资审核
     * @Date 2021/12/15 18:36
     * @Param [mediaAuditVo]
     * <p>
     * 开启事务
     * 关键数据-->auditMind  auditStatus id
     * 业务分析-->判断是否为空.修改
     * 修改时间重新赋值
     */
    @Override
    @Transactional
    public void MediaAudit(MediaAuditVo mediaAuditVo) {
        if (ObjectUtils.isEmpty(mediaAuditVo.getAuditMind()) ||
                ObjectUtils.isEmpty(mediaAuditVo.getAuditStatus()) ||
                ObjectUtils.isEmpty(mediaAuditVo.getId())) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        Media media = this.getById(mediaAuditVo.getId());
        if (ObjectUtils.isEmpty(media)) {
            ExceptionCast.cast(CommonErrorCode.E_100104);
        }
        if (!(media.getAuditStatus().equals(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode()))) {
            ExceptionCast.cast(CommonErrorCode.E_110012);
        }

        LambdaUpdateWrapper<Media> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Media::getId, mediaAuditVo.getId());
        updateWrapper.set(Media::getAuditMind, mediaAuditVo.getAuditMind());
        updateWrapper.set(Media::getAuditStatus, mediaAuditVo.getAuditStatus());
        updateWrapper.set(Media::getChangeDate, LocalDateTime.now());
        boolean update = this.update(updateWrapper);
        if (!update) {
            ExceptionCast.cast(CommonErrorCode.E_110011);
        }
    }

    /**
     * @param mediaId
     * @return java.lang.String
     * @Description //课程预览获取阿里云视频地址
     * @Date 2021/12/15 18:56
     * @Param [mediaId] 媒资id
     * 不开事务
     * 关键数据-->媒资id
     * 业务数据-->是否有数据.状态是否为审核通过.审核未通过.已提交
     */
    @Override
    public String mediaPreview(Long mediaId) {
        if (ObjectUtils.isEmpty(mediaId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        Media media = this.getById(mediaId);
        if (ObjectUtils.isEmpty(media)) {
            ExceptionCast.cast(CommonErrorCode.E_100104);
        }
        if (!(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode().equals(media.getAuditStatus())) &&
                !(media.getAuditStatus().equals(CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode())) &&
                !(media.getAuditStatus().equals(CourseAuditEnum.AUDIT_DISPAST_STATUS.getCode()))) {
            ExceptionCast.cast(CommonErrorCode.E_403000);
        }
        //初始化客户端
        try {
            DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);

            GetPlayInfoResponse playInfo = AliyunVODUtil.getPlayInfo(client, media.getFileId());

            //获取地址-->视频可能存在播放清晰度.所以为集合形式
            List<GetPlayInfoResponse.PlayInfo> list = playInfo.getPlayInfoList();
            String playURL = "";
            if (!(CollectionUtils.isEmpty(list))) {
                GetPlayInfoResponse.PlayInfo info = list.get(0);
                playURL = info.getPlayURL();
            }
            return playURL;
        } catch (Exception e) {
            //切记不能用 e.printStackTrace();
            log.error("当钱错误；{}", e.getMessage());
            return null;
        }
    }

    /**
     * @param mediaId
     * @return com.xuecheng.common.domain.response.RestResponse
     * @Description //
     * @Date 2021/12/16 16:56
     * 根据媒资id获取媒资信息
     * @Param [mediaId]
     * 业务分析
     * 不开事务
     * 关键数据-->mediaId
     * 业务数据-->审核是否通过/是否被删除
     *
     *
     */
    @Override
    public RestResponse<MediaDTO> getById4Service(Long mediaId) {
        //关键数据判断
        if (ObjectUtils.isEmpty(mediaId)){
            ExceptionCast.cast(CommonErrorCode.E_100110);
        }
        Media media = this.getById(mediaId);
        //判断业务数据
        if (ObjectUtils.isEmpty(media)){
            ExceptionCast.cast(CommonErrorCode.E_100104);
            return null;
        }else {
            MediaDTO mediaDTO = MapStructMedia.INSTANCE.po2DTO(media);
            RestResponse<MediaDTO> success = RestResponse.success(mediaDTO);
            return success;

        }
    }
}
